package com.imagination.applet.controller.api;

import com.alibaba.fastjson.JSONObject;
import com.imagination.applet.controller.api.request.*;
import com.imagination.applet.controller.api.response.BuildVirtualIdentityImageResponse;
import com.imagination.applet.controller.api.response.QueryTrainingVirtualIdentityResponse;
import com.imagination.applet.controller.api.response.QueryVirtualIdentityResponse;
import com.imagination.applet.controller.api.response.UserPhotosResponse;
import com.imagination.applet.controller.view.VirtualIdentityVO;
import com.imagination.applet.controller.web.configuration.UserHolder;
import com.imagination.applet.domain.adapter.os.OSSAdapter;
import com.imagination.applet.domain.photo.model.UserPhoto;
import com.imagination.applet.domain.photo.model.UserPhotosResult;
import com.imagination.applet.domain.product.model.ProductImage;
import com.imagination.applet.domain.product.service.ProductImageQueryService;
import com.imagination.applet.domain.revenue.identity.model.vo.VirtualIdentityImageResult;
import com.imagination.applet.domain.revenue.identity.service.VirtualIdentityBuildingService;
import com.imagination.applet.domain.revenue.identity.service.VirtualIdentityImageService;
import com.imagination.applet.domain.utils.ImagePathGenerator;
import com.imagination.applet.infrastructure.common.RestResponse;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/virtual-identity")
public class VirtualIdentityController {

    private final VirtualIdentityBuildingService virtualIdentityBuildingService;
    private final VirtualIdentityImageService imageService;


    @PostMapping(value = "/submit")
    public RestResponse<VirtualIdentityVO> submit(@RequestBody VirtualIdentitySubmitParam param) {
        return RestResponse.ok(virtualIdentityBuildingService.submitNoPay(param));
    }

    @GetMapping
    public RestResponse<QueryVirtualIdentityResponse> fetchVirtualIdentity() {
        List<VirtualIdentityVO> list = virtualIdentityBuildingService.fetchVirtualIdentity();
        return RestResponse.ok(QueryVirtualIdentityResponse.of(list));
    }

    @PostMapping("/del")
    public RestResponse<Void> remove(@RequestBody VirtualIdentitySubmitParam param) {
        virtualIdentityBuildingService.remove(param.getId());
        return RestResponse.ok();
    }

    @GetMapping("/training")
    public RestResponse<QueryTrainingVirtualIdentityResponse> fetchTrainingVirtualIdentity() {
        VirtualIdentityVO virtualIdentityVO = virtualIdentityBuildingService.fetchTrainingVirtualIdentity();
        Integer waitListCount = virtualIdentityBuildingService.fetchTrainingVirtualIdentityCount();
        QueryTrainingVirtualIdentityResponse response = new QueryTrainingVirtualIdentityResponse();
        response.setVirtualIdentityVO(virtualIdentityVO);
        response.setWaitListCount(waitListCount);
        response.setEstimatedWaitingSeconds(waitListCount * 120L);
        return RestResponse.ok(response);
    }

    @PostMapping(value = "/check")
    public RestResponse<Boolean> check() {
        return RestResponse.ok(virtualIdentityBuildingService.check());
    }

    @PostMapping(value = "/images")
    public RestResponse<BuildVirtualIdentityImageResponse> buildImages(@RequestBody VirtualIdentityImagesParam param) {
        JSONObject jsonObject = imageService.inferenceImages(param);
        return RestResponse.ok(BuildVirtualIdentityImageResponse.builder()
                .taskId(jsonObject.getString("taskId"))
                        .waitingTime(jsonObject.getInteger("waiting_time"))
                        .waitingTasks(jsonObject.getInteger("waiting_tasks"))
                .build());
    }

    private final OSSAdapter ossAdapter;

    @PostMapping("uploadImage2caricature")
    public RestResponse<String> uploadImage2caricature(@NotNull @RequestPart MultipartFile photo) throws Exception {
        final String key = UserPhoto.PREFIX_PATH + ImagePathGenerator.next(photo.getOriginalFilename());
        ossAdapter.putObject(key, photo.getInputStream());
        return RestResponse.ok(key);
    }


    @PostMapping(value = "/image2caricature")
    public RestResponse<BuildVirtualIdentityImageResponse> image2caricature(@RequestBody Image2caricatureParam param) {
        JSONObject jsonObject = imageService.image2caricature(param);
        return RestResponse.ok(BuildVirtualIdentityImageResponse.builder()
                .taskId(jsonObject.getString("taskId"))
                .waitingTime(jsonObject.getInteger("waiting_time"))
                .waitingTasks(jsonObject.getInteger("waiting_tasks"))
                .build());
    }




    private final ProductImageQueryService productImageQueryService;



    @PostMapping(value = "/imageHD")
    public RestResponse<BuildVirtualIdentityImageResponse> buildImages(@RequestBody ImageHDParam imageHDParam) {
        ProductImage productImage = productImageQueryService.getById(imageHDParam.getProductImageId());
        JSONObject jsonObject = imageService.imageHD(productImage, 1);
        return RestResponse.ok(BuildVirtualIdentityImageResponse.builder()
                .taskId(jsonObject.getString("taskId"))
                .waitingTime(jsonObject.getInteger("waiting_time"))
                .waitingTasks(jsonObject.getInteger("waiting_tasks"))
                .build());
    }

    @GetMapping(value = "/images")
    public RestResponse<VirtualIdentityImageResult> getImages(@RequestParam String taskId) {
        return RestResponse.ok(imageService.queryImages(taskId));
    }
}
